package diamondServer.businesslogic.configs;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import diamondServer.businesslogic.resource.ResourceData;



/**
 * Reads resources configuration on the server from a XML file.
 * <p>
 * For now it recognize configuration changes by changes in the names of 
 * resource files.
 * 
 * </p><p>
 * TODO: recognize changes also by last modified file flags or by some 
 * 		 additional fields in the XML file.
 * </p>
 */
public class XMLResourceDataReader
	implements ResourceDataReader
{
	private File mXmlFile;
	private XMLReader mParser;
	private Set<ResourceData> mCurrResourcesData;
	private Set<ResourceData> mNewResourcesData;
	
	public XMLResourceDataReader(File xmlFile) 
		throws SAXException
	{
		mCurrResourcesData = new HashSet<ResourceData>();
		mXmlFile = xmlFile;
		mParser = XMLReaderFactory.createXMLReader();
		mParser.setContentHandler(
			new Handler()); //handler is an inner class
	}

	@Override
	public Set<ResourceData> read() 
		throws IOException, SAXException 
	{
		//TODO: add schema validation
		mNewResourcesData = new HashSet<ResourceData>(); //empty set
		mParser.parse(mXmlFile.getPath());
		mCurrResourcesData.addAll(mNewResourcesData);
		return mNewResourcesData;
	}
	
	
	
/* ------------------- PARSE HANDLER ------------------ */
	
private enum Element
{ NONE, SERVICE_CLASS_NAME, MESSAGE_CLASS_NAME };
	
/**
 * fills mAddedResourcesData
 */
class Handler extends DefaultHandler {
	
	private Element currElement = Element.NONE; 
	private String currMessageClassName;

	@Override
	public void characters(char ch[], int start, int length)
	throws SAXException {
		
		if (Element.NONE == currElement)
			return;
		
		String str = new String(ch, start, length)
			.replaceAll("\\s+", ""); //remove all spaces 
		
		if (Element.MESSAGE_CLASS_NAME == currElement){
			currMessageClassName = str;
		}
		
		if (Element.SERVICE_CLASS_NAME == currElement){
			ResourceData rData = 
				new ResourceData(str, currMessageClassName);			
			if (!mCurrResourcesData.contains(rData)){
				mNewResourcesData.add(rData);	
			}
		}	
	}

	@Override
	public void startElement
	(String uri, String localName, String qName,Attributes attributes)
	throws SAXException {
		
		if (localName.equals("ServiceClassName"))
			currElement = Element.SERVICE_CLASS_NAME;
		else if (localName.equals("MessageClassName"))
			currElement = Element.MESSAGE_CLASS_NAME;

	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		currElement = Element.NONE;
	}

}//closing the inner class	
}//closing the public class
